package com.iot08.api.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iot08.api.constant.Constant;
import com.iot08.api.service.AccountService;
import com.iot08.api.service.ChatGroupService;
import com.iot08.api.service.WxVipCnsService;
import com.iot08.api.service.WxgzConfigService;
import com.iot08.api.service.supplement.WeixinService;
import com.iot08.api.service.supplement.WxWebApiService;
import com.iot08.api.utils.CXUtil;
import com.iot08.api.utils.FileUtil;
import com.iot08.api.utils.XMLUtils;
import com.iot08.api.utils.request.ParamHandle;
import com.iot08.api.vo.request.*;
import com.iot08.common.entity.app.Account;
import com.iot08.common.entity.app.WxVipcns;
import com.iot08.common.entity.app.Wxgzconfig;
import com.iot08.common.utils.CollectionUtil;
import com.iot08.common.utils.DateUtil;
import com.iot08.common.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * 赛诺的公众号配置
 * @time: 4/8/22 5:55 PM
 * @author: Weichao
 * @version 1.0
 */
@Slf4j
@RestController
@RequestMapping("getway")
public class TxWxWebApiController {

    @Resource
    private WxWebApiService wxWebApiService;
    @Resource
    private AccountService accountService;
    @Resource
    private WxgzConfigService wxgzConfigService;
    @Resource
    private WeixinService weixinService;

    @Resource
    private WxVipCnsService wxVipCnsService;

    /**
     * 配置微信公众号时，需要验证消息的确来自微信服务器
     *
     * @time: 2021/4/27 11:31
     * @author: Rock
     * @version 1.0
     */
    @GetMapping("accounts/wx_login")
    public void wxLoginCheck(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Map<String, String> params = ParamHandle.getRequestParams(request);
        log.info("wxLoginCheck params = {}", params);
        if (params != null && StringUtil.isNotBlank(params.get("timestamp")) && StringUtil.isNotBlank(params.get("nonce"))
                && StringUtil.isNotBlank(params.get("signature")) && StringUtil.isNotBlank(params.get("echostr"))) {
            List<String> temp = new ArrayList<>();
            temp.add("jianyou123");
            temp.add(params.get("timestamp").toString());
            temp.add(params.get("nonce").toString());
            Collections.sort(temp);
            String value = "";
            for (String s : temp) {
                value += s;
            }
            value = CXUtil.byte2hex(CXUtil.getSHA1Digest(value));
            if (params.get("signature").toString().toUpperCase().equals(value)) {
                response.setHeader("Content-Type", "text");
                response.getWriter().write(params.get("echostr").toString().toCharArray());
            }
        }
    }

    /**
     * 微信用户 的统一事件回调接口 (用来关联微信unionid)
     * @param xmlStr
     * @param request
     * @param response
     * @throws IOException
     */
    @PostMapping("accounts/wx_login")
    public void wxLogin(@RequestBody String xmlStr, HttpServletRequest request, HttpServletResponse response) throws IOException {
        WxLoginReqXmlVO xmlVO = (WxLoginReqXmlVO) XMLUtils.convertXmlStrToObject(WxLoginReqXmlVO.class, xmlStr);
        log.info("wxLogin xmlVO = {}", xmlVO);
        response.setHeader("Content-Type", "text");
        Map<String, String> params = ParamHandle.getRequestParams(request);
        log.info("wxLogin params = {}", params);
        try{
            if (params != null && xmlVO != null && StringUtil.isNotBlank(params.get("openid"))) {
                String openid = params.get("openid");
                String wxid = xmlVO.getFromUserName();
                String wxgzMasterId = xmlVO.getToUserName();
                JSONObject fileConfig = FileUtil.getFileConfig();
                if ("VIEW".equals(xmlVO.getEvent())
                        || "subscribe".equals(xmlVO.getEvent())
                        || "unsubscribe".equals(xmlVO.getEvent())
                        || "CLICK".equals(xmlVO.getEvent())) {
                    if ("subscribe".equals(xmlVO.getEvent())) {
                        //订阅公众号
                        //回复个自动回复
                        String content = fileConfig.getString("Auto_reply");
                        weixinService.replyWxMsg(Constant.WEIXIN_PUSH_TYPE_1, content, wxgzMasterId, wxid);

                        //获取 unionid
                        JSONObject wxUserInfo = weixinService.getWxUserInfo(openid, xmlVO.getToUserName());
                        String unionid = wxUserInfo.getString("unionid");

                        Account account = accountService.findOne(new Query(Criteria.where("unionid").is(unionid)));
                        Update updateAccount = new Update();
                        //公众号订阅
                        if (account != null) {
                            account.setWxgzMasterId(wxgzMasterId);
                            account.setVipcn_openid(openid);
                            account.setSubscribe(1);
                            account.setWechat_send_status(1);
                            updateAccount.set("wxgz_replyIsInvalid", 1);
                            log.info("关联unionID成功");
                            accountService.save(account);
                        }
                        if (wxVipCnsService.count(new Query(Criteria.where("openid").is(openid))) == 0) {
                            Document vipcn = new Document();
                            vipcn.put("openid", openid);
                            vipcn.put("unionid", unionid);
                            vipcn.put("subscribe_time", new Date());
                            wxVipCnsService.insertOneDoc(vipcn);
                            log.info("unionID:{} openid:{} 的微信用户 创建Vipcns 记录成功", unionid,openid);
                        }else{
                            log.info("关联unionID:{} openid:{} 的微信用户失败", unionid,openid);
                        }


                    }else if ("unsubscribe".equals(xmlVO.getEvent())) {
                        //取消订阅公众号
                        Account account = accountService.findOne(new Query(Criteria.where("vipcn_openid").is(openid)));
                        if (account != null) {
                            wxVipCnsService.delByQuery(new Query(Criteria.where("openid").is(openid)));
                            account.setSubscribe(0);
                            account.setWechat_send_status(0);
                            accountService.save(account);
                            log.info("openid:{} 的微信用户 取消订阅公众号",openid);
                        }
                    }
                }
            }
        }finally {

            response.getWriter().write("");
        }

    }

    /**
     * 定位页面授权调用的接口
     *
     * @param vo
     * @param bindingResult
     * @time: 2021/5/8 14:42
     * @author: Rock
     * @version 1.0
     */
    @PostMapping("wxOauth/getOpenId")
    public Object getOpenIdForLocAuth(@Validated WxOauthReqVO vo, BindingResult bindingResult) {
        log.info(" getOpenIdForLocAuth vo = {}", vo);
        return wxWebApiService.getOpenIdForLocAuth(vo);
    }

    /**
     * 根据code 获取的微信用户在我们系统中的信息
     *
     * @param vo
     * @param bindingResult
     * @time: 2021/5/8 10:34
     * @author: Rock
     * @version 1.0
     */
    @GetMapping("wxOauth/getOpenId")
    public Object getOpenId(@Validated WxOauthReqVO vo, BindingResult bindingResult) throws IOException {
        log.info(" getOpenId vo = {}", vo);
        return wxWebApiService.getOpenId(vo);
    }

    /**
     * 切换设备
     *
     * @param vo
     * @param bindingResult
     * @time: 2021/5/8 16:33
     * @author: Rock
     * @version 1.0
     */
    @PostMapping("wxChat/swichDevice")
    public Object swichDevice(@Validated SwichDeviceReqVO vo, BindingResult bindingResult) {
        log.info(" swichDevice vo = {}", vo);
        return wxWebApiService.swichDevice(vo);
    }

    /**
     * 获取设备最后一次定位的信息
     *
     * @param vo
     * @param bindingResult
     * @time: 2021/5/8 17:19
     * @author: Rock
     * @version 1.0
     */
    @GetMapping("wxChat/location")
    public Object getLastLocation(@Validated OpenidParamReqVO vo, BindingResult bindingResult) {
        log.info(" getLastLocation vo = {}", vo);
        return wxWebApiService.getLastLocation(vo);
    }

    /**
     * 下发设备主动定位
     *
     * @param vo
     * @param bindingResult
     * @time: 2021/5/8 17:31
     * @author: Rock
     * @version 1.0
     */
    @PostMapping("wxChat/location")
    public Object sendLastLocation(@Validated OpenidParamReqVO vo, BindingResult bindingResult) {
        log.info(" sendLastLocation vo = {}", vo);
        return wxWebApiService.sendLastLocation(vo);
    }

    /**
     * 解绑设备
     *
     * @param vo
     * @param bindingResult
     * @time: 2021/5/8 18:29
     * @author: Rock
     * @version 1.0
     */
    @PostMapping("wxChat/unBindDevice")
    public Object unBindDevice(@Validated SwichDeviceReqVO vo, BindingResult bindingResult) {
        log.info(" unBindDevice vo = {}", vo);
        return wxWebApiService.unBindDevice(vo);
    }

    /**
     * 绑定设备
     *
     * @param vo
     * @param bindingResult
     * @time: 2021/5/8 19:06
     * @author: Rock
     * @version 1.0
     */
    @PostMapping("wxChat/BindDevice")
    public Object bindDevice(@Validated BindDeviceReqVO vo, BindingResult bindingResult) throws IOException {
        log.info(" bindDevice vo = {}", vo);
        return wxWebApiService.bindDevice(vo);
    }

    /**
     * 获取微信签名
     *
     * @param vo
     * @param bindingResult
     * @time: 2021/5/8 19:08
     * @author: Rock
     * @version 1.0
     */
    @GetMapping("wxChat/BindDevice")
    public Object getWxSign(@Validated GetWxSignReqVO vo, BindingResult bindingResult) throws IOException {
        log.info(" getWxSign vo = {}", vo);
        return wxWebApiService.getWxSign(vo);
    }

    /**
     * 下发注册码
     *
     * @param vo
     * @param bindingResult
     * @time: 2021/5/14 15:52
     * @author: Rock
     * @version 1.0
     */
    @PostMapping("wxChat/sendCode")
    public Object sendCode(@Validated SendCodeReqVO vo, BindingResult bindingResult) throws IOException {
        log.info(" sendCode vo = {}", vo);
        return wxWebApiService.sendCode(vo);
    }

}
